package cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.task;

import java.util.Date;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;

import cn.stronglink.esm27.algorithm.core.util.ContextUtils;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.algorithm.IAlgorithm;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.algorithm.IAlgorithmFactory;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.algorithm.ParticleLandingAlgorithmFactory;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.entity.GasDispersionParamsEntity;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.entity.ParticleLandingAlgorithmManager;
import cn.stronglink.esm27.algorithm.iot.devices.algorithmservice.message.MQMessageOfESM27;
import cn.stronglink.esm27.algorithm.mq.TopicSender;

@Component("autoPushParticleLandingAlgorithmDatasTask")
@Lazy(false)
@EnableScheduling
public class AutoPushParticleLandingAlgorithmDatasTask implements SchedulingConfigurer {
	private static Logger logger = LogManager.getLogger(AutoPushGasAlgorithmDatasTask.class.getName());
	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");
	private final static String TOPIC_NAME = "ESM27AlgorithmToService";
	private final static String ACTION_CODE = "ParticleLandingAlgorithmResult"; // MQ中判断消息类型的标识符
	private static final String DEFAULT_CRON = "0/5 * * * * ? ";
	private String cron = DEFAULT_CRON;
	private IAlgorithm algorithm;
	private boolean isRun = false;

	public AutoPushParticleLandingAlgorithmDatasTask() {
		IAlgorithmFactory algorithmFactory = new ParticleLandingAlgorithmFactory();
		this.algorithm = algorithmFactory.createAlgorithm();
	}

	/**
	 * 获取任务执行规则
	 * 
	 * @return
	 */
	public String getCron() {
		return cron;
	}

	/**
	 * 设置任务执行规则
	 * 
	 * @param cron
	 */
	public void setCron(String cron) {
		if (cron == null || cron.isEmpty()) {
			isRun = false;
		} else {
			this.cron = cron;
			isRun = true;
		}
	}

	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		taskRegistrar.addTriggerTask(new Runnable() {
			@Override
			public void run() {
				if (isRun == false)
					return;
				
//				try {
					Object gasAlgorithmValues = this.calcGasResult();  // 计算气体扩散
					this.sendToMQ(gasAlgorithmValues);				  // 发送气体扩散数据到MQ
//				} catch (Exception e) {
//					logger.error(e);
//				}
			}

			/**
			 * 计算气体数据
			 * @return
			 */
			private Object calcGasResult() {
				GasDispersionParamsEntity plParams = ParticleLandingAlgorithmManager.getParticleLandingParams();
				Preconditions.checkNotNull(plParams);

				Object[] params = new Object[] { plParams.getAs(), plParams.getWs(),plParams.getWd(), plParams.getGd(),
						plParams.getH(), plParams.getDq(), plParams.getfCurrentTime(),plParams.getConcentration() };
				AutoPushParticleLandingAlgorithmDatasTask.this.algorithm.updateParams(params);
				plParams.setfCurrentTime(plParams.getfCurrentTime()+plParams.getPushSpanSecond());
				
				return AutoPushParticleLandingAlgorithmDatasTask.this.algorithm.calc();
			}

			/**
			 * 发送计算结果到指定MQ
			 * @param value
			 */
			private void sendToMQ(Object values) {
				MQMessageOfESM27 message = new MQMessageOfESM27();
				message.setActioncode(ACTION_CODE);
				message.setTimestamp(System.currentTimeMillis());
				message.setAwsPostdata(values);
				message.setSuccess(true);

				String json = JSON.toJSONString(message);
				topicSender.send(TOPIC_NAME, json);
				logger.info("发送[{}]到MQ完成:{}", "计算颗粒物沉降模型的信息", json);
			}
		}, new Trigger() {
			@Override
			public Date nextExecutionTime(TriggerContext triggerContext) {
				// 任务触发，可修改任务的执行周期
				CronTrigger trigger = new CronTrigger(cron);
				Date nextExec = trigger.nextExecutionTime(triggerContext);
				return nextExec;
			}
		});
	}
}

